package com.lucy.viewer.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdUtil;
import com.lucy.viewer.constant.ViewerConst;
import com.lucy.viewer.params.ViewerFile;
import com.lucy.viewer.utils.ViewerFileCache;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * @author kindear
 * 预览文件相关接口
 */
public interface ViewerFileService {
    /**
     * 上传文件，并返回可访问链接
     * @param file
     * @return
     */
    default String fileUpload(MultipartFile file){
        // 获取文件名
        String fileName = file.getOriginalFilename();
        // 获取文件类型
        String fileType = FileNameUtil.extName(fileName);
        // 选择模式
        if (ViewerConst.IMG_FILE.contains(fileType)){
            return "http://150.158.135.236:8888/down/adbo4TLeN5xe.jpg";
        }else if (ViewerConst.DOC_FILE.contains(fileType)){
            return "http://150.158.135.236:8888/down/sSvtjfBd4W4J.docx";
        }else if (ViewerConst.MUSIC_FILE.contains(fileType)){
            return "https://mpdown.kekenet.com/Sound/2020/10/cet620101302_0309819agp.mp3";
        }else {
            return "hello";
        }
    }

    /**
     * 根据文件名创建文件 -- key
     * @param fileName
     * @return
     */
    default ViewerFile fileTouch(String fileName){
        // 获取文件后缀
        String fileType = FileNameUtil.extName(fileName);

        // 基础默认路径
        String baseDir = ViewerConst.tempFilePath();
        // 空文件创建
        ViewerFile file = new ViewerFile();
        // 文件类型
        file.setFileType(fileType);
        file.setFileName(fileName);
        file.setTitle(fileName);
        // 随机key
        String key = IdUtil.fastSimpleUUID();
        file.setKey(key);
        // 获取文件路径
        String filePath = baseDir + key + '.' + fileType;
        // 创建文件
        FileUtil.touch(filePath);
        file.setPath(filePath);
        // 文件访问链接
        file.setUrl("/viewer/download/"+key);
        return file;
    }

    default ViewerFile createViewerFile(ViewerFile viewerFile){
        ViewerFile customFile = createCustomViewerFile(viewerFile);
        if (Validator.isEmpty(customFile)){
            return createLocalViewerFile(viewerFile);
        }
        return customFile;
    }

    /**
     * 第三方文件系统中创建文件
     * @param viewerFile
     * @return
     */
     ViewerFile createCustomViewerFile(ViewerFile viewerFile);
    /**
     * 创建本地文件
     * @param viewerFile
     * @return
     */
    default ViewerFile createLocalViewerFile(ViewerFile viewerFile){
        // 写入缓存
        ViewerFileCache.put(viewerFile.getKey(), viewerFile);
        // 不做额外处理
        return viewerFile;
    }

    /**
     * 获取文件流
     * @param fileKey
     * @return
     */
    default InputStream getViewerFileStream(String fileKey) throws IOException {
        InputStream stream = getCustomViewerFileStream(fileKey);
        if (Validator.isNotEmpty(stream)){
            return stream;
        }
        return getLocalViewerFileStream(fileKey);
    }

    /**
     * 获取本地文件流
     * @param fileKey
     * @return
     * @throws IOException
     */
    default InputStream getLocalViewerFileStream(String fileKey) throws IOException {
        ViewerFile file = getLocalViewerFile(fileKey);
        String filePath = file.getPath();
        return FileUtil.getInputStream(filePath);
        //return inputStream;
    }

    /**
     * 获取第三方文件系统流
     * @param fileKey
     * @return
     */
    InputStream getCustomViewerFileStream(String fileKey);

    /**
     * 根据 key 获取文件信息
     * @param fileKey
     * @return
     */
    default ViewerFile getViewerFile(String fileKey){
        // 查询第三方文件系统
        ViewerFile customFile = getCustomViewerFile(fileKey);
        // 如果第三方文件系统不为空
        if (Validator.isNotEmpty(customFile)){
            return customFile;
        }
        // 查询本地文件系统
        ViewerFile localFile = getLocalViewerFile(fileKey);
        if (Validator.isNotEmpty(localFile)){
            return localFile;
        }
        return null;
    }



    /**
     * 获取本地文件
     * @param fileKey
     * @return
     */
    default ViewerFile getLocalViewerFile(String fileKey){
        return ViewerFileCache.get(fileKey);
    }

    /**
     * 第三方文件信息获取
     * @param fileKey
     * @return
     */
    ViewerFile getCustomViewerFile(String fileKey);


    /**
     * 文件信息修改
     * @param stream
     * @param fileKey
     * @return
     */
    default ViewerFile updateViewerFile(InputStream stream,String fileKey){
        // 查询第三方文件系统
        ViewerFile customFile = getCustomViewerFile(fileKey);
        // 如果第三方文件系统不为空
        if (Validator.isNotEmpty(customFile)){
            return updateCustomViewerFile(stream,fileKey);
        }
        // 查询key
        ViewerFile localFile = getLocalViewerFile(fileKey);
        // 如果本地文件不为空
        if (Validator.isNotEmpty(localFile)){
            return updateLocalViewerFile(stream,fileKey);
        }
        return null;
    }

    /**
     * 本地文件更新
     * @param stream
     * @param fileKey
     * @return
     */
    default ViewerFile updateLocalViewerFile(InputStream stream,String fileKey){
        // 查询key
        ViewerFile viewerFile = getLocalViewerFile(fileKey);
        // 获取文件路径
        String filePath = viewerFile.getPath();
        // 写入
        FileUtil.writeFromStream(stream,filePath);
        // 返回
        return viewerFile;
    }

    /**
     * 第三方文件信息修改
     * @param stream
     * @param fileKey
     * @return
     */
    ViewerFile updateCustomViewerFile(InputStream stream, String fileKey);

    /**
     * 第三方文件创建
     * @param stream
     * @param fileName
     * @return
     */
//    ViewerFile createCustomFile(InputStream stream,String fileName);

    /**
     * 获取文件类型
     *
     * @param fileExt
     * @return
     */
    default String getContentType(String fileExt) {
        // 文件的后缀名
        if ("bmp".equalsIgnoreCase(fileExt)) {
            return "image/bmp";
        }
        if ("gif".equalsIgnoreCase(fileExt)) {
            return "image/gif";
        }
        if ("jpeg".equalsIgnoreCase(fileExt) || "jpg".equalsIgnoreCase(fileExt) || ".png".equalsIgnoreCase(fileExt)) {
            return "image/jpeg";
        }
        if ("png".equalsIgnoreCase(fileExt)) {
            return "image/png";
        }
        if ("html".equalsIgnoreCase(fileExt)) {
            return "text/html";
        }
        if ("txt".equalsIgnoreCase(fileExt)) {
            return "text/plain";
        }
        if ("vsd".equalsIgnoreCase(fileExt)) {
            return "application/vnd.visio";
        }
        if ("ppt".equalsIgnoreCase(fileExt) || "pptx".equalsIgnoreCase(fileExt)) {
            return "application/vnd.ms-powerpoint";
        }
        if ("doc".equalsIgnoreCase(fileExt) || "docx".equalsIgnoreCase(fileExt)) {
            return "application/msword";
        }
        if ("xml".equalsIgnoreCase(fileExt)) {
            return "text/xml";
        }
        return "";
    }

    default ResponseEntity<byte[]> previewMethod(InputStream in, HttpServletRequest request, ViewerFile fileEntity){
        HttpHeaders heads = new HttpHeaders();

        String fileName = fileEntity.getFileName();
        // 指定文件类型
        heads.add(HttpHeaders.CONTENT_TYPE, getContentType(FileNameUtil.extName(fileName)));

        try {
            if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
                // firefox浏览器
                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            } else if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
                // IE浏览器
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else if (request.getHeader("User-Agent").toUpperCase().indexOf("EDGE") > 0) {
                // WIN10浏览器
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else if (request.getHeader("User-Agent").toUpperCase().indexOf("CHROME") > 0) {
                // 谷歌
                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            } else {
                //万能乱码问题解决
                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            }
        } catch (UnsupportedEncodingException e) {
            // log.error("", e);
        }
        // 标记为浏览器显示
        heads.add(HttpHeaders.CONTENT_DISPOSITION, "inline;filename=" + fileName);

        try {
            // 输入流转换为字节流
            byte[] buffer = FileCopyUtils.copyToByteArray(in);
            //file.delete();
            return new ResponseEntity<>(buffer, heads, HttpStatus.OK);
        } catch (Exception e) {
            // log.error("", e);
        }
        return null;
    }

    default ResponseEntity<byte[]> downloadMethod(InputStream in,HttpServletRequest request,ViewerFile fileEntity){

        HttpHeaders heads = new HttpHeaders();
        heads.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream; charset=utf-8");
        String fileName = fileEntity.getFileName();
        try {
            if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
                // firefox浏览器
                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            } else if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
                // IE浏览器
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else if (request.getHeader("User-Agent").toUpperCase().indexOf("EDGE") > 0) {
                // WIN10浏览器
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else if (request.getHeader("User-Agent").toUpperCase().indexOf("CHROME") > 0) {
                // 谷歌
                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            } else {
                //万能乱码问题解决
                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            }
        } catch (UnsupportedEncodingException e) {
            // log.error("", e);
        }
        heads.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + fileName);
        try {
            // 输入流转换为字节流
            byte[] buffer = FileCopyUtils.copyToByteArray(in);
            //file.delete();
            return new ResponseEntity<>(buffer, heads, HttpStatus.OK);
        } catch (Exception e) {
            // log.error("", e);
        }
        return null;
    }
}
